#ifndef AVALON_DECODER_HPP
#define AVALON_DECODER_HPP
#include "Avalon/Codecs/Codecs.hpp"
#include "Avalon/IO/IO.hpp"

namespace Avalon {
namespace Codecs {

  /*! \class Decoder
   *  \brief Interface for decoding data.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class Decoder {
    public:

      virtual ~Decoder();

      //! Checks if decoding data in place is supported.
      /*!
        \return <code>true</code> iff decoding data in place is supported.
      */
      virtual bool IsDecodeInPlaceSupported() = 0;

      //! Decodes data.
      /*!
        \param data The data to decode.
        \param size The size of the data.
        \return The decoded data.
      */
      IO::Buffer Decode(const void* data, int size);

      //! Decodes data.
      /*!
        \param data The data to decode.
        \return The decoded data.
      */
      IO::Buffer Decode(const IO::Buffer& data);

      //! Decodes data to a specified destination.
      /*!
        \param source The source data to decode.
        \param sourceSize The size of the <i>source</i>.
        \param destination The destination of the decoded <i>source</i>.
        \param destinationSize The size of the <i>destination</i>.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>source</i>.
      */
      virtual void Decode(const void* source, int sourceSize, void* destination,
        int destinationSize, int* decodedSize = NULL) = 0;

      //! Decodes data to a specified destination.
      /*!
        \param source The source data to decode.
        \param destination The destination of the decoded <i>source</i>.
        \param destinationSize The size of the <i>destination</i>.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>source</i>.
      */
      void Decode(const IO::Buffer& source, void* destination,
        int destinationSize, int* decodedSize = NULL);

      //! Decodes data to a specified destination.
      /*!
        \param source The source data to decode.
        \param sourceSize The size of the source data.
        \param destination The destination of the decoded <i>source</i>.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>source</i>.
      */
      virtual void Decode(const void* source, int sourceSize,
        IO::Buffer* destination, int* decodedSize = NULL) = 0;

      //! Decodes data to a specified destination.
      /*!
        \param source The source data to decode.
        \param destination The destination of the decoded <i>source</i>.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>source</i>.
      */
      void Decode(const IO::Buffer& source, IO::Buffer* destination,
        int* decodedSize = NULL);

      //! Decodes data in place.
      /*!
        \param data The data to decode in place.
        \param size The size of the <i>data</i>.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>data</i>.
      */
      virtual void DecodeInPlace(void* data, int size, int* decodedSize = NULL);

      //! Decodes data in place.
      /*!
        \param data The data to decode in place.
        \param decodedSize [out] The number of bytes used to decode the
                                 <i>data</i>.
      */
      void DecodeInPlace(IO::Buffer* data, int* decodedSize = NULL);
  };
}
}

#endif // AVALON_DECODER_HPP
